package com.rongke.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.rongke.commons.FailException;
import com.rongke.commons.JsonCodeEnum;
import com.rongke.commons.JsonResp;
import com.rongke.mapper.AdminMapper;
import com.rongke.mapper.ChannelMapper;
import com.rongke.mapper.UserMapper;
import com.rongke.model.Admin;
import com.rongke.model.Channel;
import com.rongke.model.User;
import com.rongke.redis.RedisClusterCache;
import com.rongke.service.AdminService;
import com.rongke.service.UserService;
import com.rongke.utils.Md5;
import com.rongke.utils.RequestUtil;
import com.rongke.utils.StringUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @AdminServiceImpl
 * @管理员ServiceImpl
 * @version : Ver 1.0
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private SessionDAO sessionDAO;

    @Autowired
    private RedisClusterCache redisClusterCache;

    @Autowired
    private ChannelMapper channelMapper;

    public List<Admin> selectAdmin(Map map){
         return adminMapper.selectAdmin(map);
    }
    public  Integer  selectAdminCount(Map map){
        return adminMapper.selectAdminCount(map);
    }
    /**
     * 登录
     * @param userName 用户名
     * @param password 密码
     * @return JsonResp
     */
    public JsonResp loginadmin(String userName, String password){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, Md5.md5Encode(password));
        try {
            //踢除用户
            this.kickOutUser(token);
        }catch (Exception e) {
            String message = e.getMessage();
            if (!message.contains("There is no session with id [")) {
                e.printStackTrace();
            }
        }finally {
            this.kickOutUser(token);
        }
        try{
            subject.login(token);
            Session session = subject.getSession();
            Serializable sessionId = session.getId();
            System.out.println("sessionId:"+sessionId);
            System.out.println("sessionHost:"+session.getHost());
            System.out.println("sessionTimeout:"+session.getTimeout());
            System.out.println(userName+"登录成功");
            Channel channel=channelMapper.selectByUserName(userName);
            Admin admin = adminMapper.selectByUserName(userName);

            if(admin!=null){
                //删除其他登陆信息
                if(admin.getToken() != null &&!sessionId.toString().equals(admin.getToken())){
                    redisClusterCache.delCache(admin.getToken());
                }
                admin.setToken(sessionId.toString());
                adminMapper.updateById(admin);
                return JsonResp.ok(admin);
            }else if (channel!=null){

                if(channel.getToken() != null &&!sessionId.toString().equals(channel.getToken())){
                    redisClusterCache.delCache(channel.getToken());
                }
                channel.setToken(sessionId.toString());
                channelMapper.updateById(channel);
                return JsonResp.ok(channel);
            }else{
                throw new FailException("用户名或密码错误！");
            }

        }catch(Exception e){
            throw new FailException("用户名或密码错误！");
        }
    }



/***
 *踢出管理员
 * */
    /**
     * 踢除用户
     * http://www.ithao123.cn/content-7174367.html
     */
    private void kickOutUser(UsernamePasswordToken token){
        String loginName = token.getUsername();
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for(Session session:sessions){
            if (session.getTimeout()==0) {
                sessionDAO.delete(session);
            }
            if(loginName.equals(String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)))) {
                //设置session立即失效，即将其踢出系统
                session.setTimeout(0);
                logout();
            }
        }
    }


    /**
     * 退出登录
     */
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            // session 会销毁，在SessionListener监听session销毁，清理权限缓存
            subject.logout();
        }
    }




    /**
     * 获取当前后台登陆用户
     *
     * @return JsonResp
     */
    public Map findLoginUser() {
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection collection = subject.getPrincipals();
        Admin user = null;
        Channel channel=null;
        if (null != collection && !collection.isEmpty()) {//web 端
            String userName = (String) collection.iterator().next();
            user = adminMapper.selectByUserName(userName);
             channel=channelMapper.selectByUserName(userName);
            if (user == null && channel==null) throw new FailException(JsonCodeEnum.OVERTIME.getMessage());
            if (user != null) {
                if (user.getStatus() == 2) {
                    throw new FailException(JsonCodeEnum.STOP.getMessage());
                }
                Map map=new HashMap();
                map.put("user",user);
                map.put("channel",channel);
                return map;
            }
            if (channel != null) {
                if (channel.getStatus() == 2) {
                    throw new FailException(JsonCodeEnum.STOP.getMessage());
                }
                Map map=new HashMap();
                map.put("user",user);
                map.put("channel",channel);
                return map;
            }
        }
        if (null == collection) {//手机端
            HttpServletRequest request = RequestUtil.getRequest();
            //请求方发送的token
            String token = request.getHeader("x-client-token");
            if (StringUtil.isNotEmpty(token)) user = adminMapper.selectByToken(token);
            if (user != null) {
                if (user.getStatus() == 2){
                    throw new FailException(JsonCodeEnum.STOP.getMessage());
                }
                Map map=new HashMap();
                map.put("user",user);
                map.put("channel",channel);
                return map;
            }
            if (StringUtil.isNotEmpty(token)) channel = channelMapper.selectByToken(token);
            if (channel != null) {
                if (channel.getStatus() == 2){
                    throw new FailException(JsonCodeEnum.STOP.getMessage());
                }
                Map map=new HashMap();
                map.put("user",user);
                map.put("channel",channel);
                return map;
            }
        }
        throw new FailException(JsonCodeEnum.OVERTIME.getMessage());
    }
}
